<template>
  <AdVxeModal
    v-bind="$attrs"
    @register="register"
    :id="formIndex"
    :title="`${t('report.route.print.printSetup.printTemplateTitle')} - ${
      FormModeEntityRef.Display
    }`"
    :help-message="`${t('common.form')}：${formIndex}`"
    :cancelText="t('common.cancelText')"
    :close-func="handleClose"
    :okText="FormModeEntityRef.OkBtnTitle"
    @ok="handleOk"
    @open-change="handleOpenChange"
    width="60%"
  >
    <a-row @contextmenu="handleContextMenu">
      <a-col :xs="24" :sm="19" :md="20" :lg="21" :xl="21" :xxl="22" :xxxl="22">
        <BasicForm @register="registerForm">
          <template #templateFileConnections="{ model, field }">
            <CodeEditor v-model:value="model[field]" :mode="MODE.JSON" :lineNumbers="true" />
          </template>
          <template #templateFileDsConfig="{ model, field }">
            <CodeEditor v-model:value="model[field]" :mode="MODE.XML" :lineNumbers="true" />
          </template>
        </BasicForm>
      </a-col>
      <a-col :xs="24" :sm="5" :md="4" :lg="3" :xl="3" :xxl="2" :xxxl="2">
        <div style="margin: 0 auto; text-align: center">
          <div>
            <Tooltip :title="t('report.route.print.printSetup.downloadDsConnectionsText')">
              <a-button color="error" shape="circle" @click="handleGetDsConnections">
                <Icon icon="uil:file-download-alt" />
              </a-button>
            </Tooltip>
          </div>
          <div style="margin-top: 0.5rem">
            <Tooltip :title="t('report.route.print.printSetup.downloadDsConfigText')">
              <a-button color="error" shape="circle" @click="handleGetDsConfigXml">
                <Icon icon="mdi:auto-download" />
              </a-button>
            </Tooltip>
          </div>
          <div style="margin-top: 0.5rem">
            <Tooltip :title="t('report.route.print.printSetup.downloadPrintTemplateText')">
              <a-button color="error" shape="circle" @click="handleGetPrintTemplate">
                <Icon icon="mdi:file-download-outline" />
              </a-button>
            </Tooltip>
          </div>
          <div style="margin-top: 0.5rem">
            <Tooltip :title="t('report.route.print.printSetup.uploadDsConnectionsText')">
              <Upload
                :showUploadList="false"
                :multiple="false"
                :accept="uploadDsConnectionsFormat"
                :beforeUpload="handleBeforeDsConnectionsUpload"
              >
                <a-button
                  color="success"
                  shape="circle"
                  :disabled="
                    formModeRef === FormModeEnum.Delete ||
                    formModeRef === FormModeEnum.Ok ||
                    formModeRef === FormModeEnum.ReadOnly
                  "
                >
                  <Icon icon="uil:file-upload-alt" />
                </a-button>
              </Upload>
            </Tooltip>
          </div>
          <div style="margin-top: 0.5rem">
            <Tooltip :title="t('report.route.print.printSetup.uploadDsConfigText')">
              <Upload
                :showUploadList="false"
                :multiple="false"
                :accept="uploadDsConfigFormat"
                :beforeUpload="handleBeforeDsConfigUpload"
              >
                <a-button
                  color="success"
                  shape="circle"
                  :disabled="
                    formModeRef === FormModeEnum.Delete ||
                    formModeRef === FormModeEnum.Ok ||
                    formModeRef === FormModeEnum.ReadOnly
                  "
                >
                  <Icon icon="mdi:auto-upload" />
                </a-button>
              </Upload>
            </Tooltip>
          </div>
          <div style="margin-top: 0.5rem">
            <Tooltip :title="t('report.route.print.printSetup.uploadPrintTemplateText')">
              <Upload
                :showUploadList="false"
                :multiple="false"
                :accept="uploadRptFileFormat"
                :beforeUpload="handleBeforeRptFileUpload"
              >
                <a-button
                  color="success"
                  shape="circle"
                  :disabled="
                    formModeRef === FormModeEnum.Delete ||
                    formModeRef === FormModeEnum.Ok ||
                    formModeRef === FormModeEnum.ReadOnly
                  "
                >
                  <Icon icon="mdi:file-upload-outline" />
                </a-button>
              </Upload>
            </Tooltip>
          </div>
          <Authority :value="'Root.Report.Admin.Print.GetDsConnections'">
            <div style="margin-top: 0.5rem">
              <Tooltip :title="t('report.route.print.printSetup.downloadDsConnectionsDemoText')">
                <a-button type="default" shape="circle" @click="handleGetDsConnectionsDemo">
                  <Icon icon="mdi:code-json" />
                </a-button>
              </Tooltip>
            </div>
          </Authority>
          <Authority :value="'Root.Report.Admin.Print.GetDsConfigXml'">
            <div style="margin-top: 0.5rem">
              <Tooltip :title="t('report.route.print.printSetup.downloadDsConfigDemoText')">
                <a-button type="default" shape="circle" @click="handleGetDsConfigXmlDemo">
                  <Icon icon="mdi:xml" />
                </a-button>
              </Tooltip>
            </div>
          </Authority>
          <Authority :value="'Root.Report.Admin.Print.GetReportFile'">
            <div style="margin-top: 0.5rem">
              <Tooltip :title="t('report.route.print.printSetup.downloadPrintTemplateDemoText')">
                <a-button type="default" shape="circle" @click="handleGetPrintTemplateDemo">
                  <Icon icon="mdi:file" />
                </a-button>
              </Tooltip>
            </div>
          </Authority>
          <Authority :value="'Root.Report.Admin.Print.ReadPrintUserNodes'">
            <div style="margin-top: 0.5rem">
              <Tooltip :title="t('report.route.print.printSetup.assignUserText')">
                <a-button type="primary" @click="handleSetUsersModalOpen">
                  <Icon icon="majesticons:users-line" />
                </a-button>
              </Tooltip>
            </div>
          </Authority>
          <Authority :value="'Root.Report.Admin.Print.ReadPrintOrganizationNodes'">
            <div style="margin-top: 0.5rem">
              <Tooltip :title="t('report.route.print.printSetup.assignOrganizationText')">
                <a-button type="primary" @click="handleSetOrganizationsModalOpen">
                  <Icon icon="clarity:organization-line" />
                </a-button>
              </Tooltip>
            </div>
          </Authority>
        </div>
      </a-col>
    </a-row>
  </AdVxeModal>

  <PrintTemplateModal @register="templateModalRegister" v-bind="templateModalProps" />
  <PrintUserTransferModal
    @register="registerSetUsersModal"
    :title="t('report.route.print.printSetup.assignUserText')"
    :search="true"
    :closeFunc="handleSetUsersModalClose"
    :okText="t('common.updateText')"
    :okAuthority="true"
    :okAuthorityCode="'Root.Report.Admin.Print.SetPrintUsers'"
    :okFunc="handleSetUsersModalOk"
    width="50%"
  />
  <PrintOrganizationTransferModal
    @register="registerSetOrganizationsModal"
    :title="t('report.route.print.printSetup.assignOrganizationText')"
    :search="true"
    :closeFunc="handleSetOrganizationsModalClose"
    :okText="t('common.updateText')"
    :okAuthority="true"
    :okAuthorityCode="'Root.Report.Admin.Print.SetPrintOrganizations'"
    :okFunc="handleSetOrganizationsModalOk"
    width="50%"
  />
</template>

<script lang="ts" setup>
  import type { PropType } from 'vue';
  import { h, ref } from 'vue';
  import { Select, Upload, Row, Col, Tooltip } from 'ant-design-vue';
  import { useMessage } from '@/hooks/web/useMessage';

  import { Authority } from '@/components/Authority';
  import { AdVxeModal, useModal, useModalInner } from '@/components/AdVxeModal';
  import { BasicForm, useForm, FormSchema } from '@/components/Form';
  import { TagEditor } from '@/components/Tag';
  import Icon from '@/components/Icon/Icon.vue';
  import { CodeEditor, MODE } from '@/components/CodeMirrorEditor';
  import { PrintTemplateModal, useAdPrint } from '@/components/AdPrint';

  import { useI18n } from '@/hooks/web/useI18n';
  import { useContextMenu } from '@/hooks/web/useContextMenu';
  import { destroyContextMenu } from '@/components/ContextMenu';
  import { isFunction } from '@/utils/is';
  import { getFileExtname, getBase64WithFile } from '@/utils/common';
  import { downloadByData, downloadByBase64 } from '@/utils/file/download';

  import { FormModeEnum, FormModeEntity } from '@/enums/formEnum';

  import { getPrintReportDsModeEnumSchema } from '@/enums/report/printReportDsModeEnum';
  import {
    PrintReportTypeEnum,
    getPrintReportTypeEnumSchema,
  } from '@/enums/report/printReportTypeEnum';

  import { readEntityInfoNodes } from '@/api/authorization/admin/entityinfo';
  import { AjaxResult } from '#/request';
  import {
    PrintOutputDto,
    PrintTemplateInputDto,
    PrintTemplateOutputDto,
    PrintTemplateFileOutputDto,
  } from '@/api/report/admin/print/model';
  import {
    getReportFile,
    getDsConnections,
    getDsConfigXml,
    createTemplates,
    updateTemplates,
    deleteTemplates,
    getTemplateFile,
    readPrintUserNodes,
    setPrintUsers,
    readPrintOrganizationNodes,
    setPrintOrganizations,
  } from '@/api/report/admin/print';

  import UserTransferModal from '@/views/system/identity/user/UserTransferModal.vue';
  import OrganizationTransferModal from '@/views/system/identity/organization/OrganizationTransferModal.vue';

  const ARow = Row;
  const ACol = Col;
  const PrintUserTransferModal = UserTransferModal;
  const PrintOrganizationTransferModal = OrganizationTransferModal;

  defineOptions({ name: 'PrintTemplateDetailModal' });
  const props = defineProps({
    /** 关闭回调，返回true关闭窗体 */
    closeFunc: {
      type: Function as PropType<
        (
          formMode: FormModeEnum,
          printRecord: PrintOutputDto | undefined,
          templateRecord: PrintTemplateInputDto | undefined,
        ) => Promise<boolean>
      >,
      default: null,
    },
    /** 提交前回调，返回false不执行内置提交逻辑，返回true执行内置提交逻辑 */
    beforeSubmitFunc: {
      type: Function as PropType<
        (
          formMode: FormModeEnum,
          printRecord: PrintOutputDto | undefined,
          templateRecord: PrintTemplateInputDto | undefined,
        ) => Promise<boolean>
      >,
      default: null,
    },
    /** 提交后回调，返回true关闭窗体 */
    afterSubmitFunc: {
      type: Function as PropType<
        (
          formMode: FormModeEnum,
          result: AjaxResult | null | undefined,
          printRecord: PrintOutputDto | undefined,
          templateRecord: PrintTemplateInputDto | undefined,
        ) => Promise<boolean>
      >,
      default: null,
    },
  });

  const { t } = useI18n();
  const { createMessage } = useMessage();
  const [createContextMenu] = useContextMenu();
  const formIndex = 'print_template_detail';
  const keyField = 'Id';

  const formModeRef = ref<FormModeEnum>(FormModeEnum.Ok);
  const FormModeEntityRef = ref<FormModeEntity>(new FormModeEntity(formModeRef.value));

  const printOutputDtoRef = ref<PrintOutputDto>();

  const uploadDsConnectionsFormat = ref('.json,.txt');
  const uploadDsConfigFormat = ref('.xml');

  // const fastReportFormat = ['frx', 'fr3', 'rdl'];
  const fastReportFormat = ['frx', '.frx'];
  const uploadRptFileFormat = ref('.frx');

  const schemas: FormSchema[] = [
    {
      field: 'Id',
      helpMessage: `${t('common.field')}：${'Id'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.templateIdTitle'),
      componentProps: { disabled: true },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'PrintId',
      helpMessage: `${t('common.field')}：${'PrintId'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.printIdTitle'),
      componentProps: { disabled: true },
      ifShow: false,
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateName',
      helpMessage: `${t('common.field')}：${'TemplateName'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.templateNameTitle'),
      required: true,
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateType',
      helpMessage: `${t('common.field')}：${'TemplateType'}`,
      component: 'Select',
      label: t('report.route.print.printSetup.templateTypeTitle'),
      required: true,
      render: ({ model, field }) => {
        return h(Select, {
          options: [...getPrintReportTypeEnumSchema()],
          showSearch: true,
          optionFilterProp: 'label',
          value: model[field],
          onChange: (e: any) => {
            model[field] = e;
            switch (e) {
              case 1: // FastReport
                uploadRptFileFormat.value = '.frx';
                break;
            }
          },
        });
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'Enabled',
      helpMessage: `${t('common.field')}：${'Enabled'}`,
      component: 'Switch',
      label: t('report.route.print.printSetup.enabledTitle'),
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'EnableFrom',
      helpMessage: `${t('common.field')}：${'EnableFrom'}`,
      component: 'DatePicker',
      label: t('report.route.print.printSetup.enableFromTitle'),
      componentProps: {
        disabled: false,
        showTime: false,
        valueFormat: 'YYYY-MM-DD',
        style: { width: '100%' },
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
      dynamicDisabled: ({ values }) => {
        return !values.Enabled;
      },
    },
    {
      field: 'EnableTo',
      helpMessage: `${t('common.field')}：${'EnableTo'}`,
      component: 'DatePicker',
      label: t('report.route.print.printSetup.enableToTitle'),
      componentProps: {
        disabled: false,
        showTime: false,
        valueFormat: 'YYYY-MM-DD',
        style: { width: '100%' },
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
      dynamicDisabled: ({ values }) => {
        return values.Enabled === undefined || values.Enabled === null || values.Enabled === false;
      },
    },
    {
      field: 'Comments',
      helpMessage: `${t('common.field')}：${'Comments'}`,
      component: 'InputTextArea',
      label: t('report.route.print.printSetup.commentsTitle'),
      // componentProps: { showCount: false, autosize: { minRows: 2, maxRows: 6 } },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 24, // ≥1200px
        xxl: 24, // ≥1600px
        // xxxl: 24, // ≥2000px 3.0
      },
    },
    {
      field: 'Tag',
      helpMessage: `${t('common.field')}：${'Tag'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.tagTitle'),
      // componentProps: { showCount: false, autosize: { minRows: 2, maxRows: 6 } },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 24, // ≥1200px
        xxl: 24, // ≥1600px
        // xxxl: 24, // ≥2000px 3.0
      },
      render: ({ model, field }) => {
        return h(TagEditor, {
          value: model[field],
          editEnabled:
            formModeRef.value === FormModeEnum.Add || formModeRef.value === FormModeEnum.Edit,
          addTagText: t('common.addText'),
          randomColor: true,
          onChange: (tags: string[]) => {
            model[field] = tags;
          },
        });
      },
    },
    {
      field: 'UserAsgn',
      helpMessage: `${t('common.field')}：${'UserAsgn'}`,
      component: 'Switch',
      label: t('report.route.print.printSetup.userAsgnTitle'),
      colProps: {
        // span: 8,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 12, // ≥768px
        lg: 12, // ≥992px
        xl: 8, // ≥1200px
        xxl: 8, // ≥1600px
        // xxxl: 8, // ≥2000px 3.0
      },
    },
    {
      field: 'OrgAsgn',
      helpMessage: `${t('common.field')}：${'OrgAsgn'}`,
      component: 'Switch',
      label: t('report.route.print.printSetup.orgAsgnTitle'),
      colProps: {
        // span: 8,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 12, // ≥768px
        lg: 12, // ≥992px
        xl: 8, // ≥1200px
        xxl: 8, // ≥1600px
        // xxxl: 8, // ≥2000px 3.0
      },
    },
    {
      field: 'LogEnabled',
      helpMessage: `${t('common.field')}：${'LogEnabled'}`,
      component: 'Switch',
      label: t('report.route.print.printSetup.logEnabledTitle'),
      colProps: {
        // span: 8,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 12, // ≥768px
        lg: 12, // ≥992px
        xl: 8, // ≥1200px
        xxl: 8, // ≥1600px
        // xxxl: 8, // ≥2000px 3.0
      },
    },
    {
      field: 'DataVersion',
      helpMessage: `${t('common.field')}：${'DataVersion'}`,
      component: 'Input',
      label: t('entity.dataVersion.dataVersionTitle'),
      componentProps: { disabled: true },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    { field: 'divider-basic', component: 'Divider', label: '', colProps: { span: 24 } },
    {
      field: 'TemplateFile.FileName',
      helpMessage: `${t('common.field')}：${'TemplateFile.FileName'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.fileNameTitle'),
      required: true,
      componentProps: { disabled: true },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateFile.FileBase64',
      helpMessage: `${t('common.field')}：${'TemplateFile.FileBase64'}`,
      component: 'InputTextArea',
      label: t('report.route.print.printSetup.fileBase64Title'),
      componentProps: { disabled: true },
      ifShow: false,
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 24, // ≥1200px
        xxl: 24, // ≥1600px
        // xxxl: 24, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateFile.DsMode',
      helpMessage: `${t('common.field')}：${'TemplateFile.DsMode'}`,
      component: 'Select',
      label: t('report.route.print.printSetup.dsModeTitle'),
      defaultValue: 2,
      required: true,
      render: ({ model, field }) => {
        return h(Select, {
          options: [...getPrintReportDsModeEnumSchema()],
          showSearch: true,
          optionFilterProp: 'label',
          value: model[field],
          onChange: async (e: any) => {
            model[field] = e;
            switch (e) {
              case 1: // Push
                break;
              case 2: // Pull
                break;
            }
          },
        });
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateFile.UseCurDb',
      helpMessage: `${t('common.field')}：${'TemplateFile.UseCurDb'}`,
      component: 'Switch',
      label: t('report.route.print.printSetup.useCurDbTitle'),
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
      dynamicDisabled: ({ values }) => {
        values = getInputDto();
        return values.TemplateFile?.DsMode === 1;
      },
    },
    {
      field: 'TemplateFile.EntityTypeName',
      helpMessage: `${t('common.field')}：${'TemplateFile.EntityTypeName'}`,
      component: 'ApiSelect',
      componentProps: {
        api: readEntityInfoNodes,
        // use name as label
        labelField: 'Name',
        // use TypeName as value
        valueField: 'TypeName',
        // not request untill to select
        immediate: true,
        showSearch: true,
        optionFilterProp: 'label',
      },
      label: t('report.route.print.printSetup.entityTypeNameTitle'),
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
      dynamicDisabled: ({ values }) => {
        values = getInputDto();
        return values.TemplateFile?.DsMode === 1 || values.TemplateFile?.UseCurDb === false;
      },
    },
    {
      field: 'TemplateFile.Connections',
      helpMessage: `${t('common.field')}：${'TemplateFile.Connections'}`,
      // component: 'Input',
      label: t('report.route.print.printSetup.connectionsTitle'),
      slot: 'templateFileConnections',
      colProps: {
        // span: 16,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 24, // ≥1200px
        xxl: 24, // ≥1600px
        // xxxl: 24, // ≥2000px 3.0
      },
      dynamicDisabled: ({ values }) => {
        values = getInputDto();
        return values.TemplateFile?.DsMode === 2;
      },
    },
    {
      field: 'TemplateFile.DsConfig',
      helpMessage: `${t('common.field')}：${'TemplateFile.DsConfig'}`,
      // component: 'Input',
      label: t('report.route.print.printSetup.dsConfigTitle'),
      slot: 'templateFileDsConfig',
      dynamicDisabled: ({ values }) => {
        values = getInputDto();
        return values.TemplateFile?.DsMode === 2;
      },
      colProps: {
        // span: 16,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 24, // ≥1200px
        xxl: 24, // ≥1600px
        // xxxl: 24, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateFile.SHA1',
      helpMessage: `${t('common.field')}：${'TemplateFile.SHA1'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.sha1Title'),
      componentProps: { disabled: true },
      ifShow: ({ values }) => {
        values = getInputDto();
        return values.TemplateFile?.SHA1;
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateFile.MD5',
      helpMessage: `${t('common.field')}：${'TemplateFile.MD5'}`,
      component: 'Input',
      label: t('report.route.print.printSetup.md5Title'),
      componentProps: { disabled: true },
      ifShow: ({ values }) => {
        values = getInputDto();
        return values.TemplateFile?.MD5;
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'TemplateFile.DataVersion',
      helpMessage: `${t('common.field')}：${'TemplateFile.DataVersion'}`,
      component: 'Input',
      label: t('entity.dataVersion.dataVersionTitle'),
      componentProps: { disabled: true },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    { field: 'divider-basic', component: 'Divider', label: '', colProps: { span: 24 } },
    {
      field: 'CreatedTime',
      helpMessage: `${t('common.field')}：${'CreatedTime'}`,
      component: 'DatePicker',
      label: t('entity.creationAudited.createdTimeTitle'),
      componentProps: {
        disabled: true,
        showTime: true,
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
        style: { width: '100%' },
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
    {
      field: 'UpdatedTime',
      helpMessage: `${t('common.field')}：${'UpdatedTime'}`,
      component: 'DatePicker',
      label: t('entity.updateAudited.updatedTimeTitle'),
      componentProps: {
        disabled: true,
        showTime: true,
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
        style: { width: '100%' },
      },
      colProps: {
        // span: 12,
        xs: 24, // <576px
        sm: 24, // ≥576px
        md: 24, // ≥768px
        lg: 24, // ≥992px
        xl: 12, // ≥1200px
        xxl: 12, // ≥1600px
        // xxxl: 12, // ≥2000px 3.0
      },
    },
  ];

  const [registerForm, { resetFields, getFieldsValue, setFieldsValue, validate }] = useForm({
    labelWidth: 160,
    schemas: schemas,
    showActionButtonGroup: false,
    compact: true,
  });

  const [register, { setModalProps, closeModal, changeLoading }] = useModalInner(async (data) => {
    changeLoading(true);
    try {
      await clearInputDto();
      const templateRecord = (data.templateRecord || {}) as PrintTemplateOutputDto;
      const printRecord = data.printRecord;
      if (printRecord) {
        printOutputDtoRef.value = printRecord as PrintOutputDto;
      }
      if (data.formMode) {
        formModeRef.value = data.formMode as FormModeEnum;
        FormModeEntityRef.value = new FormModeEntity(formModeRef.value);
        switch (formModeRef.value) {
          case FormModeEnum.Add:
            templateRecord.PrintId = printOutputDtoRef.value?.Id || '0';
            templateRecord.UserAsgn = false;
            templateRecord.OrgAsgn = false;
            templateRecord.LogEnabled = false;
            templateRecord.Enabled = true;
            break;
          case FormModeEnum.Edit:
          case FormModeEnum.ReadOnly:
          case FormModeEnum.Ok:
            const result = await getTemplateFile(templateRecord.Id);
            if (result?.Type === 200) {
              const templateFileOutputDto = result.Data as PrintTemplateFileOutputDto;
              // console.log(templateFileOutputDto);
              if (templateFileOutputDto) {
                await setInputDto({
                  TemplateFile: { ...templateFileOutputDto },
                });
              }
            }
            break;
        }
      }
      await setInputDto({
        ...templateRecord,
      });
    } finally {
      changeLoading(false);
    }
  });

  //#region "加载状态"
  const loadingRef = ref(false);
  /** 开启加载状态 */
  function openLoading() {
    changeLoading(true);
    setModalProps({ okLoading: true, cancelLoading: true });
    loadingRef.value = true;
  }
  /** 关闭加载状态 */
  function closeLoading() {
    changeLoading(false);
    setModalProps({ okLoading: false, cancelLoading: false });
    loadingRef.value = false;
  }
  //#endregion
  //#region 定义高级打印
  const { printContextMenus, templateModalRegister, templateModalProps } = useAdPrint({
    formIndex: formIndex,
    keyField: keyField,
    getFormData: () => getFieldsValue(),
  });
  /** 处理上下文菜单(右键菜单) */
  function handleContextMenu(e: MouseEvent) {
    const element = document.elementFromPoint(e.clientX, e.clientY) as Element;
    const cursor = document.defaultView?.getComputedStyle(element, null).cursor;
    // console.log('handleContextMenu', {
    //   cursor: cursor,
    //   printContextMenus: printContextMenus,
    // });

    let items: any[] = [];
    switch (FormModeEntityRef.value.FormMode) {
      case FormModeEnum.Ok:
      case FormModeEnum.Edit:
      case FormModeEnum.ReadOnly:
        if (!cursor || cursor === 'default' || cursor === 'auto') {
          items = [...printContextMenus];
        }
        break;
    }
    if (items && items?.length > 0) {
      createContextMenu({
        event: e,
        styles: {
          border: '1px solid #eee',
          'border-radius': '2px',
          'box-shadow': '3px 3px 3px rgb(0 0 0 / 15%)',
        },
        items: [...items],
      });
    }
  }
  //#endregion

  /** 获取输入DTO */
  function getInputDto(): PrintTemplateInputDto {
    const record = getFieldsValue() as PrintTemplateInputDto;
    return record;
  }
  /** 设置输入DTO */
  async function setInputDto(values: any) {
    let inputDto = getInputDto();
    inputDto = { ...inputDto, ...values };
    await setFieldsValue({ ...inputDto });
  }
  /** 清除输入DTO */
  async function clearInputDto() {
    await resetFields();
  }

  /** 处理关闭按钮 */
  async function handleClose() {
    openLoading();

    const { closeFunc } = props;
    try {
      if (closeFunc && isFunction(closeFunc)) {
        const inputDto = getInputDto();
        const result = await closeFunc(
          FormModeEntityRef.value.FormMode,
          printOutputDtoRef.value,
          inputDto,
        );
        return result;
      }
    } finally {
      closeLoading();
    }
    return true;
  }
  /** 处理确定按钮 */
  async function handleOk() {
    const data = await validate();
    if (!data) return;
    //console.log(data);

    openLoading();

    const { beforeSubmitFunc, afterSubmitFunc } = props;
    try {
      const inputDto = getInputDto();
      // console.log('handleOk', inputDto);
      let innerSubmit = true;
      let innerCloseModal = true;
      if (beforeSubmitFunc && isFunction(beforeSubmitFunc)) {
        innerSubmit = await beforeSubmitFunc(
          FormModeEntityRef.value.FormMode,
          printOutputDtoRef.value,
          inputDto,
        );
      }
      let result: AjaxResult | null = null;
      if (innerSubmit) {
        switch (FormModeEntityRef.value.FormMode) {
          case FormModeEnum.Add:
            result = await createTemplates([inputDto]);
            break;
          case FormModeEnum.Edit:
            result = await updateTemplates([inputDto]);
            break;
          case FormModeEnum.Delete:
            result = await deleteTemplates([inputDto.Id]);
            break;
        }
      }
      if (afterSubmitFunc && isFunction(afterSubmitFunc)) {
        innerCloseModal = await afterSubmitFunc(
          FormModeEntityRef.value.FormMode,
          result,
          printOutputDtoRef.value,
          inputDto,
        );
      }
      if (innerCloseModal) {
        closeModal();
      }
    } finally {
      closeLoading();
    }
  }
  /** 打开或者关闭触发 */
  function handleOpenChange(open: boolean) {
    if (!open) {
      destroyContextMenu();
    }
  }

  /** 处理下载打印模板示例 */
  async function handleGetPrintTemplateDemo() {
    openLoading();
    try {
      const fieldsValue = getInputDto();
      // console.log('fieldsValue', fieldsValue);
      if (!fieldsValue.TemplateType) {
        createMessage.error(t('report.route.print.printSetup.requireTemplateTypeText'));
        return;
      }
      const result = await getReportFile(fieldsValue.TemplateType);
      // console.log('GetPrintTemplate', result);
      let fileName = 'Report';
      switch (fieldsValue.TemplateType) {
        case 1: // FastReport
          fileName = 'FastReport.frx';
          break;
      }
      downloadByData(result, fileName);
    } finally {
      closeLoading();
    }
  }
  /** 处理下载数据源连接集合示例 */
  async function handleGetDsConnectionsDemo() {
    openLoading();
    try {
      const fieldsValue = getInputDto();
      if (!fieldsValue.TemplateType) {
        createMessage.error(t('report.route.print.printSetup.requireTemplateTypeText'));
        return;
      }
      const result = await getDsConnections(fieldsValue.TemplateType);
      // console.log('GetDsConnections', result);
      // 方法1
      // const content = JSON.stringify(result);
      // const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
      // downloadByData(blob, 'DsConnections.json');
      // 方法2
      downloadByData(JSON.stringify(result), 'DsConnections.json');
    } finally {
      closeLoading();
    }
  }
  /** 处理下载数据源配置模板示例 */
  async function handleGetDsConfigXmlDemo() {
    openLoading();
    try {
      const result = await getDsConfigXml();
      // console.log('GetDsConfigXml', result);
      downloadByData(result, 'DsConfig.xml');
    } finally {
      closeLoading();
    }
  }

  /** 处理下载数据源连接集合 */
  async function handleGetDsConnections() {
    openLoading();
    try {
      const inputDto = getInputDto();
      // console.log('inputDto', inputDto);
      if (inputDto?.TemplateFile?.Connections) {
        const fileName = inputDto?.TemplateFile?.FileName
          ? `${inputDto?.TemplateFile?.FileName}_DsConnections.json`
          : 'DsConnections.json';
        downloadByData(inputDto.TemplateFile.Connections, fileName);
      } else {
        createMessage.error(t('report.route.print.printSetup.dsConnectionsEmpty'));
      }
    } finally {
      closeLoading();
    }
  }
  /** 处理下载数据源配置模板 */
  async function handleGetDsConfigXml() {
    openLoading();
    try {
      const inputDto = getInputDto();
      // console.log('inputDto', inputDto);
      if (inputDto?.TemplateFile?.DsConfig) {
        const dsConfigFileName = inputDto?.TemplateFile?.FileName
          ? `${inputDto?.TemplateFile?.FileName}_DsConfig.xml`
          : 'DsConfig.xml';
        downloadByData(inputDto.TemplateFile.DsConfig, dsConfigFileName);
      } else {
        createMessage.error(t('report.route.print.printSetup.dsConfigEmpty'));
      }
    } finally {
      closeLoading();
    }
  }
  /** 处理下载打印模板 */
  async function handleGetPrintTemplate() {
    openLoading();
    try {
      const inputDto = getInputDto();
      // console.log('inputDto', inputDto);
      if (inputDto?.TemplateFile?.FileName && inputDto?.TemplateFile?.FileBase64) {
        downloadByBase64(inputDto.TemplateFile.FileBase64, inputDto.TemplateFile.FileName);
      } else {
        createMessage.error(t('report.route.print.printSetup.printTemplateEmpty'));
      }
    } finally {
      closeLoading();
    }
  }

  /** 处理上传数据源连接集合 */
  const handleBeforeDsConnectionsUpload = async (file: File) => {
    try {
      openLoading();
      // console.log('type', file.type);
      const isJson = file.type === 'application/json' || file.type === 'text/plain';
      if (!isJson) {
        createMessage.error(t('component.upload.acceptUpload', ['json、txt']));
        return isJson;
      }
      // const isLt2M = file.size / 1024 / 1024 < 2;
      // if (!isLt2M) {
      //   createMessage.error(t('component.upload.maxSize', [isLt2M]));
      //   return isLt2M;
      // }
      // 读取文件内容
      const reader = new FileReader();
      reader.readAsText(file, 'utf-8');
      reader.onload = async () => {
        const fileContent = reader.result?.toString();
        // console.log('fileContent', fileContent);
        // 字段赋值
        await setInputDto({
          TemplateFile: {
            Connections: fileContent,
          },
        });
      };
    } finally {
      closeLoading();
    }
    return false;
  };
  /** 处理上传数据源配置模板 */
  const handleBeforeDsConfigUpload = async (file: File) => {
    try {
      openLoading();
      const isXml = file.type === 'text/xml';
      if (!isXml) {
        createMessage.error(t('component.upload.acceptUpload', ['xml']));
        return isXml;
      }
      // const isLt2M = file.size / 1024 / 1024 < 2;
      // if (!isLt2M) {
      //   createMessage.error(t('component.upload.maxSize', [isLt2M]));
      //   return isLt2M;
      // }
      // 读取文件内容
      const reader = new FileReader();
      reader.readAsText(file, 'utf-8');
      reader.onload = async () => {
        const fileContent = reader.result?.toString();
        // console.log('fileContent', fileContent);
        // 字段赋值
        await setInputDto({
          TemplateFile: {
            DsConfig: fileContent,
          },
        });
      };
    } finally {
      closeLoading();
    }
    return false;
  };
  /** 处理上传打印模板 */
  const handleBeforeRptFileUpload = async (file: File) => {
    try {
      openLoading();
      const fileExtname = getFileExtname(file.name, true);
      const isRptFile = uploadRptFileFormat.value.indexOf(fileExtname) != -1;
      if (!isRptFile) {
        createMessage.error(t('component.upload.acceptUpload', [uploadRptFileFormat.value]));
        return isRptFile;
      }
      // const isLt2M = file.size / 1024 / 1024 < 2;
      // if (!isLt2M) {
      //   createMessage.error(t('component.upload.maxSize', [isLt2M]));
      //   return isLt2M;
      // }
      const fileBase64 = await getBase64WithFile(file);
      // console.log('getBase64WithFile', { name: file.name, base64: fileBase64 });
      await setInputDto({
        TemplateFile: {
          FileName: file.name,
          FileExtension: fileExtname,
          FileBase64: fileBase64.result,
        },
      });
      if (fastReportFormat.includes(fileExtname)) {
        await setInputDto({
          TemplateType: PrintReportTypeEnum.FastReport,
        });
      }
    } finally {
      closeLoading();
    }
    return false;
  };

  //#region "设置用户"
  const [registerSetUsersModal, setUsersModalMethods] = useModal();
  /** 处理打开设置用户弹窗 */
  async function handleSetUsersModalOpen() {
    const inputDto = getInputDto();
    if (!inputDto?.UserAsgn) {
      createMessage.error(t('report.route.print.printSetup.enableAssignUserText'));
      return;
    }
    switch (FormModeEntityRef.value.FormMode) {
      case FormModeEnum.Edit:
      case FormModeEnum.Ok:
      case FormModeEnum.ReadOnly:
        if (inputDto && inputDto?.Id) {
          const userNodes = await readPrintUserNodes(inputDto.Id);
          setUsersModalMethods.openModal(true, {
            userNodes: userNodes,
            record: inputDto,
          });
          setUsersModalMethods.setModalProps({
            title: `${t('report.route.print.printSetup.assignUserText')} - ${
              inputDto.TemplateName
            }`,
          });
        }
        break;
    }
  }
  /** 处理设置用户弹窗关闭按钮 */
  async function handleSetUsersModalClose() {
    return true;
  }
  /** 处理设置用户弹窗确定按钮 */
  async function handleSetUsersModalOk(targetKeys: (string | bigint)[], nodes: any[], record: any) {
    if (targetKeys && nodes && record && record.Id) {
      const checkedKeys = targetKeys;
      if (checkedKeys) {
        // console.log(checkedKeys);
        const userIds = checkedKeys;
        const result = await setPrintUsers({
          TemplateId: record.Id as string,
          UserIds: [...userIds],
        });
        if (result.Succeeded) {
          createMessage.success(t('common.successText'));
          return true;
        } else {
          return false;
        }
      }
      return true;
    } else {
      return true;
    }
  }
  //#endregion

  //#region "设置组织"
  const [registerSetOrganizationsModal, setOrganizationsModalMethods] = useModal();
  /** 处理打开设置组织机构弹窗 */
  async function handleSetOrganizationsModalOpen() {
    const inputDto = getInputDto();
    if (!inputDto?.OrgAsgn) {
      createMessage.error(t('report.route.print.printSetup.enableAssignOrganizationText'));
      return;
    }
    switch (FormModeEntityRef.value.FormMode) {
      case FormModeEnum.Edit:
      case FormModeEnum.Ok:
      case FormModeEnum.ReadOnly:
        if (inputDto && inputDto?.Id) {
          const orgNodes = await readPrintOrganizationNodes(inputDto.Id);
          // console.log('print', orgNodes);
          setOrganizationsModalMethods.openModal(true, {
            organizationNodes: orgNodes,
            record: inputDto,
          });
          setOrganizationsModalMethods.setModalProps({
            title: `${t('report.route.print.printSetup.assignOrganizationText')} - ${
              inputDto.TemplateName
            }`,
          });
        }
        break;
    }
  }
  /** 处理设置组织机构弹窗关闭按钮 */
  async function handleSetOrganizationsModalClose() {
    return true;
  }
  /** 处理设置组织机构弹窗确定按钮 */
  async function handleSetOrganizationsModalOk(
    targetKeys: (string | bigint)[],
    nodes: any[],
    record: any,
  ) {
    if (targetKeys && nodes && record && record.Id) {
      const checkedKeys = targetKeys;
      if (checkedKeys) {
        // console.log(checkedKeys);
        const organizationIds = checkedKeys;
        const result = await setPrintOrganizations({
          TemplateId: record.Id as string,
          OrganizationIds: [...organizationIds],
        });
        if (result.Succeeded) {
          createMessage.success(t('common.successText'));
          return true;
        } else {
          return false;
        }
      }
      return true;
    } else {
      return true;
    }
  }
  //#endregion
</script>

<style lang="less" scoped></style>
